﻿import mx.utils.Delegate;
import com.dmotiko.general.*

class BaseClipEffects {
	
	public static var REWIND:String = "baseclip_rewind";
	public static var FADE_IN:String = "baseclip_fadeIn";
	public static var FADE_OUT:String = "baseclip_fadeOut";
	public static var INTERPOLATION:String = "baseclip_interpolation";
	public static var TIMER:String = "baseclip_timer";
	public static var DELAY:String = "baseclip_delay";
	public static var WATCH_TIME_LINE:String = "baseclip_watchTimeLine";
	
	public static function initEffects(argObject){
		if(argObject.rewind != false) BaseClipEffects.rewind();
		if(argObject.interpolate != false) BaseClipEffects.interpolate();
		if(argObject.fadeIn != false) BaseClipEffects.fadeIn();
		if(argObject.fadeOut != false) BaseClipEffects.fadeOut();
		if(argObject.delayFunction != false) BaseClipEffects.delayFunction();
		if(argObject.timer != false) BaseClipEffects.timer();
		if(argObject.watchTimeLine != false) BaseClipEffects.watchTimeLine();
	}
	
	public static function rewind(){
		if(BaseClip.prototype.rewind) return;
		BaseClip.prototype.rewind = function(argObject:Object){
			var clip = this;
			var controller:MovieClip = DummyFactory.getNextDummy(clip);
		
			controller.onEnterFrame = function(){
				if(clip._currentframe == 1){
					delete this.onEnterFrame;
					clip.dispatchEvent( { target: this, type: BaseClipEffects.REWIND } );
					
					this.removeMovieClip();
					
				} else {
					clip.prevFrame();
				}
			}
			
			controller.stopRewind = function(){
				delete this.onEnterFrame;
				this.removeMovieClip();
			}
			
			return controller;
		}
	}
	public static function interpolate(){
		if(BaseClip.prototype.interpolate) return;
		BaseClip.prototype.interpolate = function(argObject:Object){
			var clip = this;
			var prop = argObject.prop;
			var nInit = argObject.init;
			var nEnd = argObject.end;
			var nRatio = argObject.ratio;
			var root = argObject.root;
			var controller;
			(root) ? controller = DummyFactory.getNextDummy(root) : controller = DummyFactory.getNextDummy(this);
			
			var nCount = 0;
			var nLastDif;
			
			var isPositive:Boolean = nEnd > clip[prop];
			
			clip[prop] = nInit;
			
			controller.onEnterFrame = function(){
						
				if(isPositive){
					var nDif:Number = nEnd - clip[prop];
				} else {
					var nDif:Number = clip[prop] - nEnd;
				}
				
				if(nDif < 2 || nDif == nLastDif) {
					nCount++;
				}
				
				if(nDif < 0.8 || nCount > 15){
					delete this.onEnterFrame;
					clip[prop] = nEnd;
					clip.dispatchEvent( { target: this, type: BaseClipEffects.INTERPOLATION, prop: prop } );
					this.removeMovieClip();
					
				} else {
					if(isPositive){
						clip[prop] += nDif / nRatio;
					} else {
						clip[prop] -= nDif / nRatio;
					}
				}
				
				nLastDif = nDif;
			}
			
			controller.stopInterpolation = function(){
				delete this.onEnterFrame;
				this.removeMovieClip();
			}
			
			return controller;
		}
	}
	
	public static function fadeIn(){
		if(BaseClip.prototype.fadeIn) return;
		BaseClip.prototype.fadeIn = function(argObject:Object){
			var fade = this.createEmptyMovieClip("fade", this.getNextHighestDepth());
			var clip = this;
			fade.onEnterFrame = function(){
				if(clip._alpha > 97){
					clip._alpha = 100;
					delete this.onEnterFrame;
					this.removeMovieClip();
					clip.dispatchEvent( { target: this, type: BaseClipEffects.FADE_IN } );
				} else {
					clip._alpha += (100 - clip._alpha) /3;
				}
			}
		}
	}
	public static function fadeOut(){
		if(BaseClip.prototype.fadeOut) return;
		BaseClip.prototype.fadeOut = function(argObject:Object){
			var fade = this.createEmptyMovieClip("fade", this.getNextHighestDepth());
			var clip = this;
			fade.onEnterFrame = function(){
				if(clip._alpha < 3){
					clip._alpha = 0;
					delete this.onEnterFrame;
					this.removeMovieClip();
					clip.dispatchEvent( { target: this, type: BaseClipEffects.FADE_OUT } );
				} else {
					clip._alpha -= (clip._alpha) /3;
				}
			}
		}
	}
	public static function delayFunction(){
		if(BaseClip.prototype.delayFunction) return;
		BaseClip.prototype.delayFunction = function(argObject){
			var clip = this;
			var delay = this.createEmptyMovieClip("delay", this.getNextHighestDepth());
			var nDelay = argObject.delay;
			var data = argObject.data;
			var bindTo = argObject.bind;
			var fListener = argObject.listener;
			var nTimer = getTimer();
			
			delay.onEnterFrame = function(){
				if(getTimer() - nTimer > nDelay){
					delete this.onEnterFrame;
					this.removeMovieClip();
					clip.dispatchEvent( { target: this, type: BaseClipEffects.DELAY, data: data } );
				}
			}
		}
	}
	
	public static function timer(){
		if(BaseClip.prototype.timer) return;
		BaseClip.prototype.timer = function(argObject){
			var clip = this;
			var controller:MovieClip = DummyFactory.getNextDummy(clip);
			var nFrames = argObject.frames;
			var bindTo = argObject.bind;
			var fListener = argObject.listener;
			
			var nTimer:Number = getTimer();
			var nCount:Number = 0;
			
			controller.onEnterFrame = function(){
				if(nCount > nFrames){
					delete this.onEnterFrame;
					clip.dispatchEvent( { target: this, type: BaseClipEffects.TIMER } );
					this.removeMovieClip();
					
				} else {
					nCount++;
				}
			}
			
			controller.stopTimer = function(){
				delete this.onEnterFrame;
				this.removeMovieClip();
			}
			
			return controller;
		}
	}
	
	public static function watchTimeLine(){
		if(BaseClip.prototype.watchTimeLine) return;
		BaseClip.prototype.watchTimeLine = function(argObject){
			var clip = this;
			var percent = argObject.percent;
			var bindTo = argObject.bind;
			var fListener = argObject.listener;
			
			var controller = DummyFactory.getNextDummy(clip);
			
			var total:Number = clip._totalframes;
			var nFrame:Number = percent * total / 100;
			
			controller.onEnterFrame = function(){
				if(clip._currentframe >= nFrame){
					delete this.onEnterFrame;
					
					clip.dispatchEvent( { target: this, type: BaseClipEffects.WATCH_TIME_LINE, percent: percent } );
					this.removeMovieClip();
				}
			}
			
			controller.stopWatcher = function(){
				delete this.onEnterFrame;
				this.removeMovieClip();
			}
			
			return controller;
		}
	}
	
}